#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define MAX_NAME_LEN 20
#define MAX_PASS_LEN 10

typedef struct {
    char name[MAX_NAME_LEN];
    char password[MAX_NAME_LEN];
}UserInfo;

#define BANNER_NAME "name:"
#define BANNER_PASS "password:"

#define SER_ERR_MESSAGE "Serailzed FAIL!"
#define UNSER_ERR_MESSAGE "Unserailzed FAIL!"

//函数指针
typedef _Bool (*pfunc)(UserInfo*, char str[]);

//对UserInfo结构体进行序列化
_Bool serialize(UserInfo* u, char filename[])
{
    FILE* file = fopen(filename, "wb");
    if (file == NULL) {
        fclose(file);
        return false;
    }

    if (fwrite(u, sizeof(UserInfo), 1, file) > 0) {
        fclose(file);
        return true;
    } else {
        fclose(file);
        return false;
    }
}

//对UserInfo结构体反序列化
UserInfo* unserialize(char filename[])
{
    FILE* file = fopen(filename, "rb");
    if (file == NULL) {
        return NULL;
    }

    UserInfo* u = (UserInfo*)calloc(1, sizeof(UserInfo));
    int ret = fread(u, sizeof(UserInfo), 1, file);
    if (ret > 0) {
        fclose(file);
        return u;
    } else {
        fclose(file);
        return NULL;
    }
}

int main()
{
    UserInfo* u = (UserInfo*)calloc(1, sizeof(UserInfo));
    
    printf("%s", BANNER_NAME);
    scanf("%s", u->name);
    printf("%s", BANNER_PASS);
    scanf("%s", u->password);

#ifdef _WIN32
    pfunc f = serialize;
    if (!f(u, "info.data")) {
        fputs(SER_ERR_MESSAGE, stderr);
        exit(-1);
    }
#else
    if (!serialize(u, "info.data")) {
        fputs(SER_ERR_MESSAGE, stderr);
        exit(-1);
    }
#endif
    free(u);

    u = unserialize("./info.data");

    if (u != NULL) {
        printf("%s\n", u->name);
        printf("%s\n", u->password);
    } else {
        fputs(UNSER_ERR_MESSAGE, stderr);
    }

    return 0;
}